/**
 * 判断url是否为绝对路径 来自axios源码
 * Determines whether the specified URL is absolute
 *
 * @param {string} url The URL to test
 * @returns {boolean} True if the specified URL is absolute, otherwise false
 */
const isAbsoluteURL = (url: string): boolean => {
	// A URL is considered absolute if it begins with "<scheme>://" or "//" (protocol-relative URL).
	// RFC 3986 defines scheme name as a sequence of characters beginning with a letter and followed
	// by any combination of letters, digits, plus, period, or hyphen.
	return /^([a-z][a-z\d+\-.]*:)?\/\//i.test(url);
};
/**
 * url路径拼接 来自axios源码
 * Creates a new URL by combining the specified URLs
 *
 * @param {string} baseURL The base URL
 * @param {string} relativeURL The relative URL
 * @returns {string} The combined URL
 */
const combineURLs = (baseURL: string, relativeURL: string): string =>
	relativeURL
		? `${baseURL.replace(/\/+$/, "")}/${relativeURL.replace(/^\/+/, "")}`
		: baseURL;

/**
 * 根据传入的baseURL来拼接新的路径 来自axios源码
 * Creates a new URL by combining the baseURL with the requestedURL,
 * only when the requestedURL is not already an absolute URL.
 * If the requestURL is absolute, this function returns the requestedURL untouched.
 *
 * @param {string} baseURL The base URL
 * @param {string} requestedURL Absolute or relative URL to combine
 * @returns {string} The combined full path
 */
export const buildFullPath = (baseURL: string, requestedURL: string) => {
	if (baseURL && !isAbsoluteURL(requestedURL)) {
		return combineURLs(baseURL, requestedURL);
	}
	return requestedURL;
};
/**
 * 去空格
 * @param {string} str
 * @param {number} type
 * @returns {string}
 * @constructor
 */
export const trim = (str: string, type: number = 1): string => {
	switch (type) {
		case 1:
			// 所有空格
			return str.replace(/\s+/g, "");
		case 2:
			// 前后空格
			return str.trim();
		case 3:
			// 前空格
			return str.replace(/(^\s*)/g, "");
		case 4:
			// 后空格
			return str.replace(/(\s*$)/g, "");
		default:
			return str;
	}
};
// padStart 的 polyfill，来自uview-ui的源码
// 因为某些机型或情况，还无法支持es7的padStart，比如电脑版的微信小程序
export const padStartPolyfill = () => {
	if (!String.prototype.padStart) {
		// 为了方便表示这里 fillString 用了ES6 的默认参数，不影响理解
		String.prototype.padStart = function(maxLength, fillString = " ") {
			if (Object.prototype.toString.call(fillString) !== "[object String]") {
				throw new TypeError("fillString must be String");
			}
			const str = this;
			// 返回 String(str) 这里是为了使返回的值是字符串字面量，在控制台中更符合直觉
			if (str.length >= maxLength) return String(str);

			const fillLength = maxLength - str.length;
			let times = Math.ceil(fillLength / fillString.length);
			while ((times >>= 1)) {
				fillString += fillString;
				if (times === 1) {
					fillString += fillString;
				}
			}
			return fillString.slice(0, fillLength) + str;
		};
	}
};
/**
 * 遮蔽字符串
 * @returns {string}
 */
export const shield = ({
	str,
	type = 1,
	end = 3,
	start = 3,
	shieldCode = "...",
}: {
	str: string;
	type?: 1 | 2;
	end?: number;
	start?: number;
	shieldCode?: string;
}): string => {
	if (!str) {
		return str;
	}
	
	switch (type) {
		case 1:
			// 遮蔽尾部
			return str.substring(str.length - end).padStart(str.length, "*");
		case 2:
			// 遮蔽中间部分
			try {
				return `${str.substring(0, start)}${shieldCode}${str.substring(str.length - end)}`;
			} catch (e) {
				return str;
			}
		default:
			return str;
	}
};
/**
 * 遮蔽邮箱
 * @returns {string}
 */
export const shieldEmail = ({ str, start, shieldCode }: {
	str: string;
	start?: number;
	shieldCode?: string;
}):string => {
	if (!str) {
		return str;
	}
	return shield({
		str,
		type:2,
		end:str.split('@')[1]?.length||str.length,
		start,
		shieldCode,
	})
}
/**
 * 驼峰转连字符
 * @param {string} str
 * @returns {string}
 */
export const camelCaseToHyphen = (str: string): string => {
	if (!str) return str;
	return str
		.replace(/([A-Z])/g, "-$1")
		.toLowerCase()
		.slice(1);
};
/**
 * 连字符转驼峰
 * @param {string} str
 * @returns {string}
 */
export const hyphenToCamelCase = (str: string): string => {
	if (!str) return str;
	return str.replace(/\-(\w)/g, (a, b, c) => {
		return b.toLocaleUpperCase();
	});
};
/**
 * NanoID
 * 源码来自nanoid 详见：https://github.com/ai/nanoid
 * @param {number} t 生成的长度
 * @param {boolean} firstE 将返回的首字母置为"e"
 * @returns {string}
 */
// #ifndef APP||H5
const crypto = {
	getRandomValues(array: Uint8Array) {
		for (var i = 0, l = array.length; i < l; i++) {

			array[i] = Math.floor(Math.random() * 256);
		}
		return array;
	}
}
// #endif

export const nanoid = (t = 21, firstE = false) => `${firstE ? 'e' : ''}${crypto.getRandomValues(new Uint8Array(t)).reduce(((t, e) => t += (e &= 63) < 36 ? e.toString(36) : e < 62 ? (e - 26).toString(36).toUpperCase() : e > 62 ? "-" : "_"), "")}`;